using System;
using Microsoft.SPOT;

namespace Robot
{
    class SerialListener
    {
        public delegate void ByteReceivedHandler(byte value);
        public event ByteReceivedHandler ByteReceived;
        System.IO.Ports.SerialPort m_serial = null;
        bool m_continue = true;
        System.Threading.Thread m_listener = null;

        /// <summary>
        /// Constructor - Sets up serial port
        /// </summary>
        public SerialListener()
        {
            m_serial = new System.IO.Ports.SerialPort("COM1", 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
            m_serial.ReadTimeout = 500;
            m_listener = new System.Threading.Thread(new System.Threading.ThreadStart(Run));
        }

        /// <summary>
        /// Starts listening thread
        /// </summary>
        public void Start()
        {
            m_continue = true;
            if (!m_listener.IsAlive)
            {
                m_listener.Start();
            }
        }

        /// <summary>
        /// Stops listening thread
        /// </summary>
        public void Stop()
        {
            m_continue = false;
        }

        /// <summary>
        /// Reads values from serial port and publishes to subscribers
        /// </summary>
        void Run()
        {
            // Open serial port
            m_serial.Open();
            byte[] buffer = new byte[1];

            // Run until stopped
            while (m_continue)
            {
                // Try/catch is used, since we might receive a timeout
                try
                {
                    if (m_serial.Read(buffer, 0, 1) > 0)
                    {
                        if (ByteReceived != null)
                        {
                            ByteReceived(buffer[0]);
                        }
                    }
                }
                catch
                {
                }
            }

            // Please be nice and close the door behind you...
            m_serial.Close();
        }
    }
}
